Down stream analysis of the dataset ‘6_Carcinosarcoma_33x220plex’

setup

knitr::opts_knit$set(root.dir = "~/Documents/co/PECAb_paper/PECAb_dataset/")
library(tidyverse)
library(ggforce)
library(Seurat)
library(tidyverse)
source("~/R/use_function.R")
dcolor <- ggsci::scale_color_d3('category20')
dfill <- ggsci::scale_fill_d3('category20')
ccolor <- viridis::scale_color_viridis()
style <- function(x,color,method='UMAP',axis=c(1,2),Theme=NULL,
                  axis.text=FALSE,axis.title=FALSE,coord_fix =TRUE,
                  palette=TRUE,title=NULL,
                  legend=TRUE,scale_color_log10=FALSE,
                  guide_pointSize=2.5,...) {
  axis <- paste0(method,axis)
  if(is.null(Theme)) Theme <- theme_bw
  g <- ggplot() + Theme()
  g <- g + geom_point(aes_(x=as.name(axis[1]),y=as.name(axis[2]),color=as.name(color)),x,...)
  
  if(coord_fix) {
    g <- g + coord_fixed()
  }
  if(!axis.text) {
    g <- g + theme(axis.text = element_blank(),axis.ticks = element_blank())
  }
  if(!axis.title) {
    g <- g + theme(axis.title = element_blank())
  }
  if(is.null(title)) {
    g <- g + ggtitle(method) 
  }else if(!is.na(title)) {
    g <- g + ggtitle(title) 
  }
  if(!legend) g <- g + theme(legend.position = 'none')
  
  if(scale_type(as.matrix(x[,color]))=='discrete' & !is.null(guide_pointSize)) {
    g <- g + guides(color = guide_legend(override.aes = list(size=guide_pointSize)))
  }
  
  if(palette) {
    if(scale_type(as.matrix(x[,color]))=='discrete') {
      g <- g + ggsci::scale_color_d3('category20')
    }else{
      if(scale_color_log10){
        g <- g + viridis::scale_color_viridis(trans='log10')
      }else{
        g <- g + viridis::scale_color_viridis()
      }
    }
  }
  return(g)
}
tib2df <- function(tib,RowNames=1) {
  rn <- pull(tib,all_of(RowNames))
  df <- tib %>%
    select(-RowNames) %>%
    as.data.frame()
  rownames(df) <- rn
  return(df)
}

load data

data <- tibble(sampleName = c('r1','r2'),
               path1 = list.files(
                 '6_Carcinosarcoma_33x220plex/Raw/',
                 full.names = T,pattern = 'PECAb'),
               path2 = list.files(
                 '6_Carcinosarcoma_33x220plex/Raw/',
                 full.names = T,pattern = 'FISH')) %>%
  mutate(
    IF  = map(path1,~{
      .x %>% read_csv(show_col_types = F) %>% 
        unite(cell,tileID,cellID,sep = '-',remove = F) %>%
        .[,-(2:8)] %>% arrange(cell)
      }),
    FISH  = map(path2,~{
      .x %>% read_csv(show_col_types = F) %>% 
        unite(cell,tileID,cellID,sep = '-',remove = F) %>%
        .[,-(2:8)] %>% arrange(cell)
      }),
    meta = map(path1,~{
      .x %>% read_csv(show_col_types = F) %>% 
        unite(cell,tileID,cellID,sep = '-',remove = F) %>%
        .[,1:8] %>% arrange(cell)
      }),
    meta = map2(meta,IF,~mutate(.x,totalExp = rowSums(.y[,-1]))),
    meta = map2(meta,FISH,~mutate(.x,totalCount = rowSums(.y[,-1]))),
    )

QC

data %>%
  select(-IF,-FISH) %>% unnest(meta) %>%
  ggplot(aes(x,y,color=sampleName)) +
    theme_void() +
    geom_point(size=.5) + 
    facet_grid(~sampleName) + coord_fixed()

{data %>%
  select(sampleName,meta) %>% unnest(meta) %>%
  ggplot(aes(sampleName,totalExp)) + geom_violin() + geom_boxplot()}|
{data %>%
  select(sampleName,meta) %>% unnest(meta) %>%
  ggplot(aes(sampleName,totalCount+1)) + geom_violin() + geom_boxplot() + scale_y_log10()}

dataf <- data %>%
  mutate(
    idx = map(meta,~{.x$totalExp > 0.2}),
    IF = map2(IF,idx,~{.x[.y,]}),
    FISH = map2(FISH,idx,~{.x[.y,]}),
    meta = map2(meta,idx,~{.x[.y,]})
    ) %>%
  mutate(
    idx = map(meta,~{.x$totalCount > 10}),
    IF = map2(IF,idx,~{.x[.y,]}),
    FISH = map2(FISH,idx,~{.x[.y,]}),
    meta = map2(meta,idx,~{.x[.y,]})
    ) %>%
  mutate(
    idx = map(IF,~{rowSums(.x[,-1]==0)==0}),
    IF = map2(IF,idx,~{.x[.y,]}),
    FISH = map2(FISH,idx,~{.x[.y,]}),
    meta = map2(meta,idx,~{.x[.y,]}),
    nCell = map(idx,sum) %>% unlist()
    )

{dataf %>%
  select(sampleName,meta) %>% unnest(meta) %>%
  ggplot(aes(sampleName,totalExp)) + geom_violin() + geom_boxplot()}|
{dataf %>%
  select(sampleName,meta) %>% unnest(meta) %>%
  ggplot(aes(sampleName,totalCount)) + geom_violin() + geom_boxplot() + scale_y_log10()}


dataf %>%  
  ggplot(aes(sampleName,nCell)) + 
  theme_classic() +
  geom_bar(stat='identity') +
  scale_x_discrete(limits=rev) +
  theme(axis.title.y = element_blank()) +  
  coord_flip() + theme(aspect.ratio = .35) 

markers <- dataf %>%
  select(sampleName,IF) %>% unnest(IF) %>%
  unite(Cell,sampleName,cell,sep='-') %>%
  tib2df() %>% scale() %>% asinh() %>%
  .[,c('E-Cadherin','N-Cadherin','VIM')]
metaf %>%
  select(x,y,sampleName) %>%
  bind_cols(markers) %>%
  gather(key = Prot,value = Exp,-(1:3)) %>%
  ggplot(aes(x,y,color=Exp)) + geom_point(size=.25) + theme_void() + coord_fixed() + facet_grid(sampleName~Prot) + 
  scale_color_gradient2(low='#d3d3d3',high='red',mid='red',midpoint =1.5)

FISH clustering

mat <- dataf %>%
  select(sampleName,FISH) %>% unnest(FISH) %>%
  unite(Cell,sampleName,cell,sep='-') %>%
  tib2df() %>% t
mat <- mat[,a]
mat <- mat[,colSums(mat)>20]
seu <- CreateSeuratObject(mat,min.cells = 100,min.features = 30)
seu <- NormalizeData(seu,scale.factor = 500)
Performing log-normalization
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- ScaleData(seu)
Centering and scaling data matrix

  |                                                                                                                                                                                      
  |                                                                                                                                                                                |   0%
  |                                                                                                                                                                                      
  |================================================================================================================================================================================| 100%
seu <- FindVariableFeatures(seu)
Calculating gene variances
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
Calculating feature variances of standardized and clipped values
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
seu <- RunPCA(seu,features = VariableFeatures(seu))
PC_ 1 
Positive:  EFEMP2, HNRNPUL1, ENY2, DNAJC8, HOOK3, AKAP12, IER3IP1, KCTD20, ACIN1, ISCU 
       EIF4G1, ANKRD11, DHX36, DNMT3A, IRF2BP2, ITGB1, FGFR1, DUSP6, FAM32A, ARHGEF12 
       HTATSF1, FN1, HP1BP3, FOXP1, IRF2BPL, APMAP, APP, IP6K2, ANKRD12, ARID5B 
Negative:  TMBIM1, NOP53, SLK, TMCO1, SNRNP200, PTDSS1, SND1, SLC25A3, NKAPD1, SHISA5 
       NCSTN, PSMF1, PSMD13, MYO1B, TMED4, DAP3, TCF7L1, DBN1, PTBP1, PRPF19 
       NCKAP1, CTSB, PRRX1, CUX1, N4BP2L2, PSMC4, NIPBL, PTP4A2, MXRA8, TSC22D1 
PC_ 2 
Positive:  SF3B1, SFT2D2, SENP5, SENP6, WAC, SERBP1, WNK1, VPS35, WDR43, UBXN4 
       CNOT7, VCL, UQCRQ, CAVIN1, RBM25, RTF2, SDF4, UBXN1, SAR1A, SEC13 
       RTRAF, RWDD1, RAB3GAP2, SRPRB, UBE2R2, VAPA, TNPO1, RB1CC1, RHOBTB3, CDK13 
Negative:  GOLIM4, GLG1, GPS1, OAF, NSFL1C, GPBP1, GIGYF2, HMGA1, NUFIP2, GANAB 
       GCC2, GADD45GIP1, GOLM1, HDLBP, MESD, G3BP2, FAM32A, FOXP1, HIF1A, KMT2E 
       PLEC, ENY2, MED28, LMNA, PMEPA1, BABAM1, DNAJC8, POLR2F, FN1, DHX36 
PC_ 3 
Positive:  BPTF, CALD1, CAPRIN1, BABAM1, BDP1, ASH1L, ATRX, BCLAF1, CAMTA1, C9orf78 
       ATP5IF1, CADM1, BAZ2B, CTSB, CDV3, COL12A1, COL8A1, ARRDC3, CDKN1A, CEP350 
       DAAM1, CCDC80, CTBP2, ARPC5L, APMAP, CACUL1, CUX1, COPB1, DBN1, DAP3 
Negative:  TAOK1, STAT3, TERF2IP, SNX27, STT3A, SLK, STAT1, TCP1, SND1, ZC3H13 
       TM9SF3, SLC25A3, YWHAZ, YTHDF2, SHISA5, SNRNP200, YWHAB, PTDSS1, PSMF1, YIPF4 
       TCF7L1, PSMD13, PTBP1, HIF1A, PRRX1, SPRY1, GOLIM4, NUFIP2, PRPF19, GPBP1 
PC_ 4 
Positive:  MRPS21, MRPL42, MTPN, MRPL17, POLR2F, MRFAP1, PMP22, PMEPA1, MESD, PPIA 
       PLEC, MED28, MED13L, METTL9, OLFML3, OAF, CDV3, CHD9, CDKN1A, NSFL1C 
       NUFIP2, CEP350, CAPRIN1, MAP4, MCL1, CAST, CKAP5, LTBP1, MAPK1IP1L, CAVIN1 
Negative:  HTATSF1, DNMT3A, HP1BP3, DUSP6, EFEMP2, ANKRD10, ANAPC16, ANKRD11, AKAP12, DHX36 
       ACIN1, IER3IP1, ARID1B, FGFR1, DNAJC8, ARHGEF12, HOOK3, ENY2, APMAP, ISCU 
       FN1, HNRNPUL1, ITGB1, IRF2BP2, EIF4G1, ANKRD12, IP6K2, APP, FAM32A, YWHAZ 
PC_ 5 
Positive:  NCKAP1, PSMD13, MYO1B, PTBP1, PRRX1, SHISA5, NCSTN, NKAPD1, NOP53, PTDSS1 
       SLC25A3, NIPBL, PSMF1, MXRA8, PRPF19, PSMC4, N4BP2L2, SNRNP200, SLK, SND1 
       PRKAR1A, TMED4, TMBIM1, MYL9, NFKBIZ, TMCO1, CTSB, CUX1, COL8A1, CTBP2 
Negative:  RIN2, TOMM22, TMED9, RAB18, TNRC6B, TRPS1, RHOBTB3, TAOK1, STT3A, STAT3 
       UACA, RTF1, SNX27, TSPAN3, RBM25, VAPA, UBE2D3, ZC3H13, ZEB1, VCL 
       RPL13, SAR1A, RWDD1, UBXN1, SEC13, TERF2IP, YTHDF2, ZMAT2, YWHAB, UQCRQ 
ElbowPlot(seu)

Signac::DepthCor(seu,reduction = 'pca')

DimHeatmap(seu, dims = 1:6, cells = 500, balanced = TRUE)

seu <- RunUMAP(seu,dims = 2:10,min.dist = .01,n.neighbors = 20)
16:39:42 UMAP embedding parameters a = 1.896 b = 0.8006
16:39:42 Read 10180 rows and found 9 numeric columns
16:39:42 Using Annoy for neighbor search, n_neighbors = 20
16:39:42 Building Annoy index with metric = cosine, n_trees = 50
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
16:39:43 Writing NN index file to temp file /var/folders/h3/33hpf9dx699_n_0xnbwf2xyr0000gn/T//Rtmp2rDCFd/filebc3c1218d2a5
16:39:43 Searching Annoy index using 1 thread, search_k = 2000
16:39:45 Annoy recall = 100%
16:39:47 Commencing smooth kNN distance calibration using 1 thread with target n_neighbors = 20
16:39:48 Initializing from normalized Laplacian + noise (using irlba)
16:39:48 Commencing optimization for 200 epochs, with 259000 positive edges
Using method 'umap'
0%   10   20   30   40   50   60   70   80   90   100%
[----|----|----|----|----|----|----|----|----|----|
**************************************************|
16:39:51 Optimization finished
seu <- FindNeighbors(seu,dims = 2:10,k.param = 30)
Computing nearest neighbor graph
Computing SNN
seu <- FindClusters(seu,resolution = .5,algorithm = 4,method = 'igraph')
um <- Embeddings(seu[['umap']]) %>%
  as_tibble(rownames='Cell') %>%
  rename(UMAP1=2,UMAP2=3) %>%
  mutate(cluster = seu$seurat_clusters)
Metaum <- metaf %>%
  unite(Cell,sampleName,cell,remove = F,sep = '-') %>%
  inner_join(um,by = 'Cell')
style(Metaum,'cluster',size=.5)

style(Metaum,'totalCount',size=.5) + viridis::scale_color_viridis(trans='log10')
Scale for colour is already present.
Adding another scale for colour, which will replace the existing scale.

fm <- FindAllMarkers(seu,only.pos = T)
Calculating cluster 1

  |                                                  | 0 % ~calculating  
  |++                                                | 2 % ~00s          
  |+++                                               | 5 % ~00s          
  |++++                                              | 7 % ~00s          
  |+++++                                             | 9 % ~00s          
  |++++++                                            | 12% ~00s          
  |+++++++                                           | 14% ~00s          
  |+++++++++                                         | 16% ~00s          
  |++++++++++                                        | 19% ~00s          
  |+++++++++++                                       | 21% ~00s          
  |++++++++++++                                      | 23% ~00s          
  |+++++++++++++                                     | 26% ~00s          
  |++++++++++++++                                    | 28% ~00s          
  |++++++++++++++++                                  | 30% ~00s          
  |+++++++++++++++++                                 | 33% ~00s          
  |++++++++++++++++++                                | 35% ~00s          
  |+++++++++++++++++++                               | 37% ~00s          
  |++++++++++++++++++++                              | 40% ~00s          
  |+++++++++++++++++++++                             | 42% ~00s          
  |+++++++++++++++++++++++                           | 44% ~00s          
  |++++++++++++++++++++++++                          | 47% ~00s          
  |+++++++++++++++++++++++++                         | 49% ~00s          
  |++++++++++++++++++++++++++                        | 51% ~00s          
  |+++++++++++++++++++++++++++                       | 53% ~00s          
  |++++++++++++++++++++++++++++                      | 56% ~00s          
  |++++++++++++++++++++++++++++++                    | 58% ~00s          
  |+++++++++++++++++++++++++++++++                   | 60% ~00s          
  |++++++++++++++++++++++++++++++++                  | 63% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~00s          
  |++++++++++++++++++++++++++++++++++                | 67% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~00s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~00s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
Calculating cluster 2

  |                                                  | 0 % ~calculating  
  |+                                                 | 2 % ~00s          
  |++                                                | 4 % ~00s          
  |+++                                               | 6 % ~00s          
  |++++                                              | 8 % ~00s          
  |+++++                                             | 10% ~00s          
  |++++++                                            | 12% ~00s          
  |+++++++                                           | 14% ~00s          
  |++++++++                                          | 16% ~00s          
  |+++++++++                                         | 18% ~00s          
  |++++++++++                                        | 20% ~00s          
  |+++++++++++                                       | 22% ~00s          
  |++++++++++++                                      | 24% ~00s          
  |+++++++++++++                                     | 26% ~00s          
  |++++++++++++++                                    | 28% ~00s          
  |+++++++++++++++                                   | 30% ~00s          
  |++++++++++++++++                                  | 32% ~00s          
  |+++++++++++++++++                                 | 34% ~00s          
  |++++++++++++++++++                                | 36% ~00s          
  |+++++++++++++++++++                               | 38% ~00s          
  |++++++++++++++++++++                              | 40% ~00s          
  |+++++++++++++++++++++                             | 42% ~00s          
  |++++++++++++++++++++++                            | 44% ~00s          
  |+++++++++++++++++++++++                           | 46% ~00s          
  |++++++++++++++++++++++++                          | 48% ~00s          
  |+++++++++++++++++++++++++                         | 50% ~00s          
  |++++++++++++++++++++++++++                        | 52% ~00s          
  |+++++++++++++++++++++++++++                       | 54% ~00s          
  |++++++++++++++++++++++++++++                      | 56% ~00s          
  |+++++++++++++++++++++++++++++                     | 58% ~00s          
  |++++++++++++++++++++++++++++++                    | 60% ~00s          
  |+++++++++++++++++++++++++++++++                   | 62% ~00s          
  |++++++++++++++++++++++++++++++++                  | 64% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~00s          
  |++++++++++++++++++++++++++++++++++                | 68% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~00s          
  |++++++++++++++++++++++++++++++++++++              | 72% ~00s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~00s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 80% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++         | 82% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 86% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 94% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
Calculating cluster 3

  |                                                  | 0 % ~calculating  
  |+                                                 | 2 % ~00s          
  |++                                                | 3 % ~00s          
  |+++                                               | 5 % ~00s          
  |++++                                              | 7 % ~00s          
  |+++++                                             | 9 % ~00s          
  |++++++                                            | 10% ~00s          
  |+++++++                                           | 12% ~00s          
  |+++++++                                           | 14% ~00s          
  |++++++++                                          | 16% ~00s          
  |+++++++++                                         | 17% ~00s          
  |++++++++++                                        | 19% ~00s          
  |+++++++++++                                       | 21% ~00s          
  |++++++++++++                                      | 22% ~00s          
  |+++++++++++++                                     | 24% ~00s          
  |+++++++++++++                                     | 26% ~00s          
  |++++++++++++++                                    | 28% ~01s          
  |+++++++++++++++                                   | 29% ~01s          
  |++++++++++++++++                                  | 31% ~01s          
  |+++++++++++++++++                                 | 33% ~01s          
  |++++++++++++++++++                                | 34% ~01s          
  |+++++++++++++++++++                               | 36% ~01s          
  |+++++++++++++++++++                               | 38% ~01s          
  |++++++++++++++++++++                              | 40% ~01s          
  |+++++++++++++++++++++                             | 41% ~01s          
  |++++++++++++++++++++++                            | 43% ~01s          
  |+++++++++++++++++++++++                           | 45% ~01s          
  |++++++++++++++++++++++++                          | 47% ~01s          
  |+++++++++++++++++++++++++                         | 48% ~01s          
  |+++++++++++++++++++++++++                         | 50% ~00s          
  |++++++++++++++++++++++++++                        | 52% ~00s          
  |+++++++++++++++++++++++++++                       | 53% ~00s          
  |++++++++++++++++++++++++++++                      | 55% ~00s          
  |+++++++++++++++++++++++++++++                     | 57% ~00s          
  |++++++++++++++++++++++++++++++                    | 59% ~00s          
  |+++++++++++++++++++++++++++++++                   | 60% ~00s          
  |++++++++++++++++++++++++++++++++                  | 62% ~00s          
  |++++++++++++++++++++++++++++++++                  | 64% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~00s          
  |++++++++++++++++++++++++++++++++++                | 67% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~00s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~00s          
  |+++++++++++++++++++++++++++++++++++++             | 72% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 74% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 76% ~00s          
  |+++++++++++++++++++++++++++++++++++++++           | 78% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 84% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 90% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 91% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=01s  
Calculating cluster 4

  |                                                  | 0 % ~calculating  
  |+                                                 | 1 % ~01s          
  |++                                                | 3 % ~00s          
  |+++                                               | 4 % ~00s          
  |+++                                               | 5 % ~00s          
  |++++                                              | 7 % ~00s          
  |+++++                                             | 8 % ~00s          
  |+++++                                             | 10% ~00s          
  |++++++                                            | 11% ~00s          
  |+++++++                                           | 12% ~00s          
  |+++++++                                           | 14% ~00s          
  |++++++++                                          | 15% ~00s          
  |+++++++++                                         | 16% ~00s          
  |+++++++++                                         | 18% ~00s          
  |++++++++++                                        | 19% ~00s          
  |+++++++++++                                       | 21% ~00s          
  |+++++++++++                                       | 22% ~00s          
  |++++++++++++                                      | 23% ~00s          
  |+++++++++++++                                     | 25% ~00s          
  |++++++++++++++                                    | 26% ~00s          
  |++++++++++++++                                    | 27% ~00s          
  |+++++++++++++++                                   | 29% ~00s          
  |++++++++++++++++                                  | 30% ~00s          
  |++++++++++++++++                                  | 32% ~00s          
  |+++++++++++++++++                                 | 33% ~00s          
  |++++++++++++++++++                                | 34% ~00s          
  |++++++++++++++++++                                | 36% ~00s          
  |+++++++++++++++++++                               | 37% ~00s          
  |++++++++++++++++++++                              | 38% ~00s          
  |++++++++++++++++++++                              | 40% ~00s          
  |+++++++++++++++++++++                             | 41% ~00s          
  |++++++++++++++++++++++                            | 42% ~00s          
  |++++++++++++++++++++++                            | 44% ~00s          
  |+++++++++++++++++++++++                           | 45% ~00s          
  |++++++++++++++++++++++++                          | 47% ~00s          
  |++++++++++++++++++++++++                          | 48% ~00s          
  |+++++++++++++++++++++++++                         | 49% ~00s          
  |++++++++++++++++++++++++++                        | 51% ~00s          
  |+++++++++++++++++++++++++++                       | 52% ~00s          
  |+++++++++++++++++++++++++++                       | 53% ~00s          
  |++++++++++++++++++++++++++++                      | 55% ~00s          
  |+++++++++++++++++++++++++++++                     | 56% ~00s          
  |+++++++++++++++++++++++++++++                     | 58% ~00s          
  |++++++++++++++++++++++++++++++                    | 59% ~00s          
  |+++++++++++++++++++++++++++++++                   | 60% ~00s          
  |+++++++++++++++++++++++++++++++                   | 62% ~00s          
  |++++++++++++++++++++++++++++++++                  | 63% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 64% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 66% ~00s          
  |++++++++++++++++++++++++++++++++++                | 67% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 68% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 70% ~00s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~00s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~00s          
  |+++++++++++++++++++++++++++++++++++++             | 74% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~00s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 78% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 82% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 84% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 86% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 88% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 89% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 92% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 93% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 95% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 96% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 97% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 99% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
Calculating cluster 5

  |                                                  | 0 % ~calculating  
  |+                                                 | 2 % ~00s          
  |++                                                | 4 % ~00s          
  |+++                                               | 6 % ~00s          
  |++++                                              | 8 % ~00s          
  |+++++                                             | 10% ~00s          
  |++++++                                            | 12% ~00s          
  |+++++++                                           | 13% ~00s          
  |++++++++                                          | 15% ~00s          
  |+++++++++                                         | 17% ~00s          
  |++++++++++                                        | 19% ~00s          
  |+++++++++++                                       | 21% ~00s          
  |++++++++++++                                      | 23% ~00s          
  |+++++++++++++                                     | 25% ~00s          
  |++++++++++++++                                    | 27% ~00s          
  |+++++++++++++++                                   | 29% ~00s          
  |++++++++++++++++                                  | 31% ~00s          
  |+++++++++++++++++                                 | 33% ~00s          
  |++++++++++++++++++                                | 35% ~00s          
  |+++++++++++++++++++                               | 37% ~00s          
  |++++++++++++++++++++                              | 38% ~00s          
  |+++++++++++++++++++++                             | 40% ~00s          
  |++++++++++++++++++++++                            | 42% ~00s          
  |+++++++++++++++++++++++                           | 44% ~00s          
  |++++++++++++++++++++++++                          | 46% ~00s          
  |+++++++++++++++++++++++++                         | 48% ~00s          
  |+++++++++++++++++++++++++                         | 50% ~00s          
  |++++++++++++++++++++++++++                        | 52% ~00s          
  |+++++++++++++++++++++++++++                       | 54% ~00s          
  |++++++++++++++++++++++++++++                      | 56% ~00s          
  |+++++++++++++++++++++++++++++                     | 58% ~00s          
  |++++++++++++++++++++++++++++++                    | 60% ~00s          
  |+++++++++++++++++++++++++++++++                   | 62% ~00s          
  |++++++++++++++++++++++++++++++++                  | 63% ~00s          
  |+++++++++++++++++++++++++++++++++                 | 65% ~00s          
  |++++++++++++++++++++++++++++++++++                | 67% ~00s          
  |+++++++++++++++++++++++++++++++++++               | 69% ~00s          
  |++++++++++++++++++++++++++++++++++++              | 71% ~00s          
  |+++++++++++++++++++++++++++++++++++++             | 73% ~00s          
  |++++++++++++++++++++++++++++++++++++++            | 75% ~00s          
  |+++++++++++++++++++++++++++++++++++++++           | 77% ~00s          
  |++++++++++++++++++++++++++++++++++++++++          | 79% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++         | 81% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++        | 83% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++       | 85% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++      | 87% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++     | 88% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++    | 90% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++   | 92% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++  | 94% ~00s          
  |+++++++++++++++++++++++++++++++++++++++++++++++++ | 96% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 98% ~00s          
  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=00s  
genes <- fm %>% 
  as_tibble() %>% mutate(cluster = as.character(cluster)) %>%
  with(split(gene,cluster)) 
topgenes <- map(genes,~{tmp <- head(.x,min(length(.x),6)); factor(tmp,levels=tmp)})
topgenes %>% 
  lapply(function(Y){
    lapply(Y,function(y){
      data <- FetchData(object = seu, vars = y)
      data$cluster <- as.character(Idents(seu))
      y_ <- paste0("`", y, "`")
      as_tibble(data) %>%
        ggplot(aes_string(x='cluster',y=y_,fill='cluster')) +
        theme_classic() + 
        geom_violin(scale='width',adjust=1) +
        theme(legend.position = 'none',
              axis.title = element_blank(),
              panel.grid.major.x = element_blank(),
              plot.title = element_text(hjust = 0.5) ) +
        labs(title = y) + dfill
      }) %>% 
      patchwork::wrap_plots(nrow=1)
    }) %>%
  patchwork::wrap_plots(ncol=1)

idx <- Metaum %>%
  mutate(cluster = as.character(cluster)) %>%
  with(model.matrix(~0+cluster))
colnames(idx) <- sub("sampleName","",colnames(idx))
X <- dataf %>% 
  select(sampleName,IF) %>% unnest(IF) %>%
  unite(Cell,sampleName,cell,sep = '-') %>% tib2df()
X <- X[Metaum$Cell,]
avgmat <- X %>% as.matrix() %>% t %>% {t(.%*%idx)/colSums(idx)} %>% scale 
pheatmap::pheatmap(avgmat,cellwidth = 10,cellheight = 20,color=viridis::viridis(10))

pheatmap::pheatmap(asinh(avgmat),cellwidth = 10,cellheight = 20,color=viridis::viridis(10))

domi1 <- Metaum %>%
  mutate(x=floor(x/1000),y=floor(y/1000)) %>%
  count(x,y,sampleName,cluster) %>%
  group_by(x,y,sampleName) %>% arrange(-n) %>%
  summarise(tot = sum(n),
            n = head(n,1),
            dom = head(cluster,1)) %>%
  ungroup() %>%
  mutate(Accp = n/tot) 
`summarise()` has grouped output by 'x', 'y'. You can override using the `.groups` argument.
domi1 %>%
  ggplot(aes(x,y,color=dom,size=n,alpha=Accp)) + 
  theme_no_axes() + geom_point() + 
  coord_fixed() + facet_wrap(~sampleName) +
  xlim(.5,20.5) + ylim(.5,20.5) + 
  dcolor +
  labs(alpha='Accpancy',size='nTotal cell',color='dominant cluster') +
  theme(strip.background = element_blank()) 

domi2 <- Metaum %>%
  mutate(x=floor(x/1000),y=floor(y/1000),
         cluster = ifelse(cluster == 1,'Activated',cluster),
         cluster = ifelse(cluster == 2,'Epithelial',cluster),
         cluster = ifelse(cluster %in% 3:5,'Mesenchymal',cluster),
         cluster = factor(cluster,levels = c('Activated','Epithelial','Mesenchymal'))) %>%
  count(x,y,sampleName,cluster) %>%
  group_by(x,y,sampleName) %>% arrange(-n) %>%
  summarise(tot = sum(n),
            n = head(n,1),
            dom = head(cluster,1)) %>%
  ungroup() %>%
  mutate(Accp = n/tot) 
`summarise()` has grouped output by 'x', 'y'. You can override using the `.groups` argument.
domi2 %>%
  ggplot(aes(x,y,color=dom,size=n,alpha=Accp)) + 
  theme_no_axes() + geom_point() + 
  coord_fixed() + facet_wrap(~sampleName) +
  xlim(.5,20.5) + ylim(.5,20.5) + 
  scale_color_manual(values = dcolor$palette(8)[c(1,2,8)]) +
  labs(alpha='Accpancy',size='nTotal cell',color='dominant cluster') +
  theme(strip.background = element_blank()) 

sessionInfo()
R version 4.2.2 (2022-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.2.1

Matrix products: default
LAPACK: /Library/Frameworks/R.framework/Versions/4.2-arm64/Resources/lib/libRlapack.dylib

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] SeuratObject_4.1.3 Seurat_4.3.0.1     ggforce_0.4.1      lubridate_1.9.2    forcats_1.0.0      stringr_1.5.0      dplyr_1.1.2        purrr_1.0.1        readr_2.1.4       
[10] tidyr_1.3.0        tibble_3.2.1       ggplot2_3.4.2      tidyverse_2.0.0   

loaded via a namespace (and not attached):
  [1] fastmatch_1.1-3        plyr_1.8.8             igraph_1.5.0.1         lazyeval_0.2.2         sp_2.0-0               splines_4.2.2          BiocParallel_1.32.6   
  [8] listenv_0.9.0          scattermore_1.2        GenomeInfoDb_1.34.9    digest_0.6.33          htmltools_0.5.5        viridis_0.6.4          fansi_1.0.4           
 [15] magrittr_2.0.3         memoise_2.0.1          phateR_1.0.7           tensor_1.5             cluster_2.1.4          ROCR_1.0-11            limma_3.54.2          
 [22] tzdb_0.4.0             Biostrings_2.66.0      globals_0.16.2         tcltk2_1.2-11          matrixStats_1.0.0      vroom_1.6.3            timechange_0.2.0      
 [29] spatstat.sparse_3.0-2  colorspace_2.1-0       ggrepel_0.9.3          xfun_0.39              tcltk_4.2.2            crayon_1.5.2           RCurl_1.98-1.12       
 [36] jsonlite_1.8.7         progressr_0.13.0       spatstat.data_3.0-1    survival_3.5-5         zoo_1.8-12             ape_5.7-1              glue_1.6.2            
 [43] polyclip_1.10-4        gtable_0.3.3           zlibbioc_1.44.0        XVector_0.38.0         leiden_0.4.3           future.apply_1.11.0    BiocGenerics_0.44.0   
 [50] abind_1.4-5            scales_1.2.1           pheatmap_1.0.12        Signac_1.10.0          spatstat.random_3.1-5  miniUI_0.1.1.1         Rcpp_1.0.11           
 [57] viridisLite_0.4.2      xtable_1.8-4           pamr_1.56.1            reticulate_1.30        bit_4.0.5              proxy_0.4-27           stats4_4.2.2          
 [64] tsne_0.1-3.1           htmlwidgets_1.6.2      httr_1.4.6             RColorBrewer_1.1-3     ellipsis_0.3.2         ica_1.0-3              pkgconfig_2.0.3       
 [71] farver_2.1.1           sass_0.4.7             uwot_0.1.16            deldir_1.0-9           here_1.0.1             utf8_1.2.3             tidyselect_1.2.0      
 [78] labeling_0.4.2         rlang_1.1.1            reshape2_1.4.4         later_1.3.1            munsell_0.5.0          tools_4.2.2            cachem_1.0.8          
 [85] cli_3.6.1              generics_0.1.3         ggridges_0.5.4         evaluate_0.21          fastmap_1.1.1          yaml_2.3.7             goftest_1.2-3         
 [92] knitr_1.43             bit64_4.0.5            fitdistrplus_1.1-11    RANN_2.6.1             pbapply_1.7-2          future_1.33.0          nlme_3.1-162          
 [99] mime_0.12              RcppRoll_0.3.0         compiler_4.2.2         rstudioapi_0.15.0      plotly_4.10.2          png_0.1-8              e1071_1.7-13          
[106] spatstat.utils_3.0-3   tweenr_2.0.2           bslib_0.5.0            stringi_1.7.12         lattice_0.21-8         Matrix_1.5-4.1         stylo_0.7.4           
[113] ggsci_3.0.0            vctrs_0.6.3            pillar_1.9.0           lifecycle_1.0.3        jquerylib_0.1.4        spatstat.geom_3.2-4    lmtest_0.9-40         
[120] RcppAnnoy_0.0.21       bitops_1.0-7           data.table_1.14.8      cowplot_1.1.1          irlba_2.3.5.1          GenomicRanges_1.50.2   httpuv_1.6.11         
[127] patchwork_1.1.2        R6_2.5.1               promises_1.2.0.1       KernSmooth_2.23-22     gridExtra_2.3          IRanges_2.32.0         parallelly_1.36.0     
[134] codetools_0.2-19       MASS_7.3-60            rprojroot_2.0.3        withr_2.5.0            Rsamtools_2.14.0       sctransform_0.3.5      GenomeInfoDbData_1.2.9
[141] S4Vectors_0.36.2       mgcv_1.9-0             parallel_4.2.2         hms_1.1.3              grid_4.2.2             class_7.3-22           rmarkdown_2.23        
[148] Rtsne_0.16             spatstat.explore_3.2-1 shiny_1.7.4.1         
LS0tCnRpdGxlOiAiNl9DYXJjaW5vc2FyY29tYV8zM3gyMjBwbGV4IgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpEb3duIHN0cmVhbSBhbmFseXNpcyBvZiB0aGUgZGF0YXNldCAnNl9DYXJjaW5vc2FyY29tYV8zM3gyMjBwbGV4JwoKIyMgc2V0dXAKCmBgYHtyIHNldHVwfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShnZ2ZvcmNlKQpsaWJyYXJ5KFNldXJhdCkKbGlicmFyeSh0aWR5dmVyc2UpCnNvdXJjZSgifi9SL3VzZV9mdW5jdGlvbi5SIikKYGBgCgpgYGB7cn0KZGNvbG9yIDwtIGdnc2NpOjpzY2FsZV9jb2xvcl9kMygnY2F0ZWdvcnkyMCcpCmRmaWxsIDwtIGdnc2NpOjpzY2FsZV9maWxsX2QzKCdjYXRlZ29yeTIwJykKY2NvbG9yIDwtIHZpcmlkaXM6OnNjYWxlX2NvbG9yX3ZpcmlkaXMoKQpzdHlsZSA8LSBmdW5jdGlvbih4LGNvbG9yLG1ldGhvZD0nVU1BUCcsYXhpcz1jKDEsMiksVGhlbWU9TlVMTCwKICAgICAgICAgICAgICAgICAgYXhpcy50ZXh0PUZBTFNFLGF4aXMudGl0bGU9RkFMU0UsY29vcmRfZml4ID1UUlVFLAogICAgICAgICAgICAgICAgICBwYWxldHRlPVRSVUUsdGl0bGU9TlVMTCwKICAgICAgICAgICAgICAgICAgbGVnZW5kPVRSVUUsc2NhbGVfY29sb3JfbG9nMTA9RkFMU0UsCiAgICAgICAgICAgICAgICAgIGd1aWRlX3BvaW50U2l6ZT0yLjUsLi4uKSB7CiAgYXhpcyA8LSBwYXN0ZTAobWV0aG9kLGF4aXMpCiAgaWYoaXMubnVsbChUaGVtZSkpIFRoZW1lIDwtIHRoZW1lX2J3CiAgZyA8LSBnZ3Bsb3QoKSArIFRoZW1lKCkKICBnIDwtIGcgKyBnZW9tX3BvaW50KGFlc18oeD1hcy5uYW1lKGF4aXNbMV0pLHk9YXMubmFtZShheGlzWzJdKSxjb2xvcj1hcy5uYW1lKGNvbG9yKSkseCwuLi4pCiAgCiAgaWYoY29vcmRfZml4KSB7CiAgICBnIDwtIGcgKyBjb29yZF9maXhlZCgpCiAgfQogIGlmKCFheGlzLnRleHQpIHsKICAgIGcgPC0gZyArIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfYmxhbmsoKSxheGlzLnRpY2tzID0gZWxlbWVudF9ibGFuaygpKQogIH0KICBpZighYXhpcy50aXRsZSkgewogICAgZyA8LSBnICsgdGhlbWUoYXhpcy50aXRsZSA9IGVsZW1lbnRfYmxhbmsoKSkKICB9CiAgaWYoaXMubnVsbCh0aXRsZSkpIHsKICAgIGcgPC0gZyArIGdndGl0bGUobWV0aG9kKSAKICB9ZWxzZSBpZighaXMubmEodGl0bGUpKSB7CiAgICBnIDwtIGcgKyBnZ3RpdGxlKHRpdGxlKSAKICB9CiAgaWYoIWxlZ2VuZCkgZyA8LSBnICsgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnKQogIAogIGlmKHNjYWxlX3R5cGUoYXMubWF0cml4KHhbLGNvbG9yXSkpPT0nZGlzY3JldGUnICYgIWlzLm51bGwoZ3VpZGVfcG9pbnRTaXplKSkgewogICAgZyA8LSBnICsgZ3VpZGVzKGNvbG9yID0gZ3VpZGVfbGVnZW5kKG92ZXJyaWRlLmFlcyA9IGxpc3Qoc2l6ZT1ndWlkZV9wb2ludFNpemUpKSkKICB9CiAgCiAgaWYocGFsZXR0ZSkgewogICAgaWYoc2NhbGVfdHlwZShhcy5tYXRyaXgoeFssY29sb3JdKSk9PSdkaXNjcmV0ZScpIHsKICAgICAgZyA8LSBnICsgZ2dzY2k6OnNjYWxlX2NvbG9yX2QzKCdjYXRlZ29yeTIwJykKICAgIH1lbHNlewogICAgICBpZihzY2FsZV9jb2xvcl9sb2cxMCl7CiAgICAgICAgZyA8LSBnICsgdmlyaWRpczo6c2NhbGVfY29sb3JfdmlyaWRpcyh0cmFucz0nbG9nMTAnKQogICAgICB9ZWxzZXsKICAgICAgICBnIDwtIGcgKyB2aXJpZGlzOjpzY2FsZV9jb2xvcl92aXJpZGlzKCkKICAgICAgfQogICAgfQogIH0KICByZXR1cm4oZykKfQp0aWIyZGYgPC0gZnVuY3Rpb24odGliLFJvd05hbWVzPTEpIHsKICBybiA8LSBwdWxsKHRpYixhbGxfb2YoUm93TmFtZXMpKQogIGRmIDwtIHRpYiAlPiUKICAgIHNlbGVjdCgtUm93TmFtZXMpICU+JQogICAgYXMuZGF0YS5mcmFtZSgpCiAgcm93bmFtZXMoZGYpIDwtIHJuCiAgcmV0dXJuKGRmKQp9CmBgYAoKCiMjIGxvYWQgZGF0YQoKYGBge3J9CmRhdGEgPC0gdGliYmxlKHNhbXBsZU5hbWUgPSBjKCdyMScsJ3IyJyksCiAgICAgICAgICAgICAgIHBhdGgxID0gbGlzdC5maWxlcygKICAgICAgICAgICAgICAgICAnNl9DYXJjaW5vc2FyY29tYV8zM3gyMjBwbGV4L1Jhdy8nLAogICAgICAgICAgICAgICAgIGZ1bGwubmFtZXMgPSBULHBhdHRlcm4gPSAnUEVDQWInKSwKICAgICAgICAgICAgICAgcGF0aDIgPSBsaXN0LmZpbGVzKAogICAgICAgICAgICAgICAgICc2X0NhcmNpbm9zYXJjb21hXzMzeDIyMHBsZXgvUmF3LycsCiAgICAgICAgICAgICAgICAgZnVsbC5uYW1lcyA9IFQscGF0dGVybiA9ICdGSVNIJykpICU+JQogIG11dGF0ZSgKICAgIElGICA9IG1hcChwYXRoMSx+ewogICAgICAueCAlPiUgcmVhZF9jc3Yoc2hvd19jb2xfdHlwZXMgPSBGKSAlPiUgCiAgICAgICAgdW5pdGUoY2VsbCx0aWxlSUQsY2VsbElELHNlcCA9ICctJyxyZW1vdmUgPSBGKSAlPiUKICAgICAgICAuWywtKDI6OCldICU+JSBhcnJhbmdlKGNlbGwpCiAgICAgIH0pLAogICAgRklTSCAgPSBtYXAocGF0aDIsfnsKICAgICAgLnggJT4lIHJlYWRfY3N2KHNob3dfY29sX3R5cGVzID0gRikgJT4lIAogICAgICAgIHVuaXRlKGNlbGwsdGlsZUlELGNlbGxJRCxzZXAgPSAnLScscmVtb3ZlID0gRikgJT4lCiAgICAgICAgLlssLSgyOjgpXSAlPiUgYXJyYW5nZShjZWxsKQogICAgICB9KSwKICAgIG1ldGEgPSBtYXAocGF0aDEsfnsKICAgICAgLnggJT4lIHJlYWRfY3N2KHNob3dfY29sX3R5cGVzID0gRikgJT4lIAogICAgICAgIHVuaXRlKGNlbGwsdGlsZUlELGNlbGxJRCxzZXAgPSAnLScscmVtb3ZlID0gRikgJT4lCiAgICAgICAgLlssMTo4XSAlPiUgYXJyYW5nZShjZWxsKQogICAgICB9KSwKICAgIG1ldGEgPSBtYXAyKG1ldGEsSUYsfm11dGF0ZSgueCx0b3RhbEV4cCA9IHJvd1N1bXMoLnlbLC0xXSkpKSwKICAgIG1ldGEgPSBtYXAyKG1ldGEsRklTSCx+bXV0YXRlKC54LHRvdGFsQ291bnQgPSByb3dTdW1zKC55WywtMV0pKSksCiAgICApCmBgYAoKCiMjIFFDCgpgYGB7cn0KZGF0YSAlPiUKICBzZWxlY3QoLUlGLC1GSVNIKSAlPiUgdW5uZXN0KG1ldGEpICU+JQogIGdncGxvdChhZXMoeCx5LGNvbG9yPXNhbXBsZU5hbWUpKSArCiAgICB0aGVtZV92b2lkKCkgKwogICAgZ2VvbV9wb2ludChzaXplPS41KSArIAogICAgZmFjZXRfZ3JpZCh+c2FtcGxlTmFtZSkgKyBjb29yZF9maXhlZCgpCmBgYAoKYGBge3J9CntkYXRhICU+JQogIHNlbGVjdChzYW1wbGVOYW1lLG1ldGEpICU+JSB1bm5lc3QobWV0YSkgJT4lCiAgZ2dwbG90KGFlcyhzYW1wbGVOYW1lLHRvdGFsRXhwKSkgKyBnZW9tX3Zpb2xpbigpICsgZ2VvbV9ib3hwbG90KCl9fAp7ZGF0YSAlPiUKICBzZWxlY3Qoc2FtcGxlTmFtZSxtZXRhKSAlPiUgdW5uZXN0KG1ldGEpICU+JQogIGdncGxvdChhZXMoc2FtcGxlTmFtZSx0b3RhbENvdW50KzEpKSArIGdlb21fdmlvbGluKCkgKyBnZW9tX2JveHBsb3QoKSArIHNjYWxlX3lfbG9nMTAoKX0KYGBgCgoKYGBge3J9CmRhdGFmIDwtIGRhdGEgJT4lCiAgbXV0YXRlKAogICAgaWR4ID0gbWFwKG1ldGEsfnsueCR0b3RhbEV4cCA+IDAuMn0pLAogICAgSUYgPSBtYXAyKElGLGlkeCx+ey54Wy55LF19KSwKICAgIEZJU0ggPSBtYXAyKEZJU0gsaWR4LH57LnhbLnksXX0pLAogICAgbWV0YSA9IG1hcDIobWV0YSxpZHgsfnsueFsueSxdfSkKICAgICkgJT4lCiAgbXV0YXRlKAogICAgaWR4ID0gbWFwKG1ldGEsfnsueCR0b3RhbENvdW50ID4gMTB9KSwKICAgIElGID0gbWFwMihJRixpZHgsfnsueFsueSxdfSksCiAgICBGSVNIID0gbWFwMihGSVNILGlkeCx+ey54Wy55LF19KSwKICAgIG1ldGEgPSBtYXAyKG1ldGEsaWR4LH57LnhbLnksXX0pCiAgICApICU+JQogIG11dGF0ZSgKICAgIGlkeCA9IG1hcChJRix+e3Jvd1N1bXMoLnhbLC0xXT09MCk9PTB9KSwKICAgIElGID0gbWFwMihJRixpZHgsfnsueFsueSxdfSksCiAgICBGSVNIID0gbWFwMihGSVNILGlkeCx+ey54Wy55LF19KSwKICAgIG1ldGEgPSBtYXAyKG1ldGEsaWR4LH57LnhbLnksXX0pLAogICAgbkNlbGwgPSBtYXAoaWR4LHN1bSkgJT4lIHVubGlzdCgpCiAgICApCgp7ZGF0YWYgJT4lCiAgc2VsZWN0KHNhbXBsZU5hbWUsbWV0YSkgJT4lIHVubmVzdChtZXRhKSAlPiUKICBnZ3Bsb3QoYWVzKHNhbXBsZU5hbWUsdG90YWxFeHApKSArIGdlb21fdmlvbGluKCkgKyBnZW9tX2JveHBsb3QoKX18CntkYXRhZiAlPiUKICBzZWxlY3Qoc2FtcGxlTmFtZSxtZXRhKSAlPiUgdW5uZXN0KG1ldGEpICU+JQogIGdncGxvdChhZXMoc2FtcGxlTmFtZSx0b3RhbENvdW50KSkgKyBnZW9tX3Zpb2xpbigpICsgZ2VvbV9ib3hwbG90KCkgKyBzY2FsZV95X2xvZzEwKCl9CgpkYXRhZiAlPiUgIAogIGdncGxvdChhZXMoc2FtcGxlTmFtZSxuQ2VsbCkpICsgCiAgdGhlbWVfY2xhc3NpYygpICsKICBnZW9tX2JhcihzdGF0PSdpZGVudGl0eScpICsKICBzY2FsZV94X2Rpc2NyZXRlKGxpbWl0cz1yZXYpICsKICB0aGVtZShheGlzLnRpdGxlLnkgPSBlbGVtZW50X2JsYW5rKCkpICsgIAogIGNvb3JkX2ZsaXAoKSArIHRoZW1lKGFzcGVjdC5yYXRpbyA9IC4zNSkgCmBgYAoKYGBge3IgZmlnLndpZHRoPTh9Cm1hcmtlcnMgPC0gZGF0YWYgJT4lCiAgc2VsZWN0KHNhbXBsZU5hbWUsSUYpICU+JSB1bm5lc3QoSUYpICU+JQogIHVuaXRlKENlbGwsc2FtcGxlTmFtZSxjZWxsLHNlcD0nLScpICU+JQogIHRpYjJkZigpICU+JSBzY2FsZSgpICU+JSBhc2luaCgpICU+JQogIC5bLGMoJ0UtQ2FkaGVyaW4nLCdOLUNhZGhlcmluJywnVklNJyldCm1ldGFmICU+JQogIHNlbGVjdCh4LHksc2FtcGxlTmFtZSkgJT4lCiAgYmluZF9jb2xzKG1hcmtlcnMpICU+JQogIGdhdGhlcihrZXkgPSBQcm90LHZhbHVlID0gRXhwLC0oMTozKSkgJT4lCiAgZ2dwbG90KGFlcyh4LHksY29sb3I9RXhwKSkgKyBnZW9tX3BvaW50KHNpemU9LjI1KSArIHRoZW1lX3ZvaWQoKSArIGNvb3JkX2ZpeGVkKCkgKyBmYWNldF9ncmlkKHNhbXBsZU5hbWV+UHJvdCkgKyAKICBzY2FsZV9jb2xvcl9ncmFkaWVudDIobG93PScjZDNkM2QzJyxoaWdoPSdyZWQnLG1pZD0ncmVkJyxtaWRwb2ludCA9MS41KQpgYGAKCgoKCgoKIyMgRklTSCBjbHVzdGVyaW5nIAoKYGBge3Igd2FybmluZz1GfQptYXQgPC0gZGF0YWYgJT4lCiAgc2VsZWN0KHNhbXBsZU5hbWUsRklTSCkgJT4lIHVubmVzdChGSVNIKSAlPiUKICB1bml0ZShDZWxsLHNhbXBsZU5hbWUsY2VsbCxzZXA9Jy0nKSAlPiUKICB0aWIyZGYoKSAlPiUgdAptYXQgPC0gbWF0WyxhXQptYXQgPC0gbWF0Wyxjb2xTdW1zKG1hdCk+MjBdCnNldSA8LSBDcmVhdGVTZXVyYXRPYmplY3QobWF0LG1pbi5jZWxscyA9IDEwMCxtaW4uZmVhdHVyZXMgPSAzMCkKc2V1IDwtIE5vcm1hbGl6ZURhdGEoc2V1LHNjYWxlLmZhY3RvciA9IDUwMCkKc2V1IDwtIFNjYWxlRGF0YShzZXUpCnNldSA8LSBGaW5kVmFyaWFibGVGZWF0dXJlcyhzZXUpCnNldSA8LSBSdW5QQ0Eoc2V1LGZlYXR1cmVzID0gVmFyaWFibGVGZWF0dXJlcyhzZXUpKQpFbGJvd1Bsb3Qoc2V1KQpTaWduYWM6OkRlcHRoQ29yKHNldSxyZWR1Y3Rpb24gPSAncGNhJykKYGBgCgpgYGB7cn0KRGltSGVhdG1hcChzZXUsIGRpbXMgPSAxOjYsIGNlbGxzID0gNTAwLCBiYWxhbmNlZCA9IFRSVUUpCmBgYAoKYGBge3Igd2FybmluZz1GfQpzZXUgPC0gUnVuVU1BUChzZXUsZGltcyA9IDI6MTAsbWluLmRpc3QgPSAuMDEsbi5uZWlnaGJvcnMgPSAyMCkKc2V1IDwtIEZpbmROZWlnaGJvcnMoc2V1LGRpbXMgPSAyOjEwLGsucGFyYW0gPSAzMCkKc2V1IDwtIEZpbmRDbHVzdGVycyhzZXUscmVzb2x1dGlvbiA9IC41LGFsZ29yaXRobSA9IDQsbWV0aG9kID0gJ2lncmFwaCcpCmBgYAoKYGBge3J9CnVtIDwtIEVtYmVkZGluZ3Moc2V1W1sndW1hcCddXSkgJT4lCiAgYXNfdGliYmxlKHJvd25hbWVzPSdDZWxsJykgJT4lCiAgcmVuYW1lKFVNQVAxPTIsVU1BUDI9MykgJT4lCiAgbXV0YXRlKGNsdXN0ZXIgPSBzZXUkc2V1cmF0X2NsdXN0ZXJzKQpNZXRhdW0gPC0gbWV0YWYgJT4lCiAgdW5pdGUoQ2VsbCxzYW1wbGVOYW1lLGNlbGwscmVtb3ZlID0gRixzZXAgPSAnLScpICU+JQogIGlubmVyX2pvaW4odW0sYnkgPSAnQ2VsbCcpCnN0eWxlKE1ldGF1bSwnY2x1c3Rlcicsc2l6ZT0uNSkKc3R5bGUoTWV0YXVtLCd0b3RhbENvdW50JyxzaXplPS41KSArIHZpcmlkaXM6OnNjYWxlX2NvbG9yX3ZpcmlkaXModHJhbnM9J2xvZzEwJykKYGBgCgpgYGB7cn0gCmZtIDwtIEZpbmRBbGxNYXJrZXJzKHNldSxvbmx5LnBvcyA9IFQpCmdlbmVzIDwtIGZtICU+JSAKICBhc190aWJibGUoKSAlPiUgbXV0YXRlKGNsdXN0ZXIgPSBhcy5jaGFyYWN0ZXIoY2x1c3RlcikpICU+JQogIHdpdGgoc3BsaXQoZ2VuZSxjbHVzdGVyKSkgCnRvcGdlbmVzIDwtIG1hcChnZW5lcyx+e3RtcCA8LSBoZWFkKC54LG1pbihsZW5ndGgoLngpLDYpKTsgZmFjdG9yKHRtcCxsZXZlbHM9dG1wKX0pCnRvcGdlbmVzICU+JSAKICBsYXBwbHkoZnVuY3Rpb24oWSl7CiAgICBsYXBwbHkoWSxmdW5jdGlvbih5KXsKICAgICAgZGF0YSA8LSBGZXRjaERhdGEob2JqZWN0ID0gc2V1LCB2YXJzID0geSkKICAgICAgZGF0YSRjbHVzdGVyIDwtIGFzLmNoYXJhY3RlcihJZGVudHMoc2V1KSkKICAgICAgeV8gPC0gcGFzdGUwKCJgIiwgeSwgImAiKQogICAgICBhc190aWJibGUoZGF0YSkgJT4lCiAgICAgICAgZ2dwbG90KGFlc19zdHJpbmcoeD0nY2x1c3RlcicseT15XyxmaWxsPSdjbHVzdGVyJykpICsKICAgICAgICB0aGVtZV9jbGFzc2ljKCkgKyAKICAgICAgICBnZW9tX3Zpb2xpbihzY2FsZT0nd2lkdGgnLGFkanVzdD0xKSArCiAgICAgICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gJ25vbmUnLAogICAgICAgICAgICAgIGF4aXMudGl0bGUgPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgICAgICAgcGFuZWwuZ3JpZC5tYWpvci54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgICAgICAgIHBsb3QudGl0bGUgPSBlbGVtZW50X3RleHQoaGp1c3QgPSAwLjUpICkgKwogICAgICAgIGxhYnModGl0bGUgPSB5KSArIGRmaWxsCiAgICAgIH0pICU+JSAKICAgICAgcGF0Y2h3b3JrOjp3cmFwX3Bsb3RzKG5yb3c9MSkKICAgIH0pICU+JQogIHBhdGNod29yazo6d3JhcF9wbG90cyhuY29sPTEpCmBgYAoKCmBgYHtyfQppZHggPC0gTWV0YXVtICU+JQogIG11dGF0ZShjbHVzdGVyID0gYXMuY2hhcmFjdGVyKGNsdXN0ZXIpKSAlPiUKICB3aXRoKG1vZGVsLm1hdHJpeCh+MCtjbHVzdGVyKSkKY29sbmFtZXMoaWR4KSA8LSBzdWIoInNhbXBsZU5hbWUiLCIiLGNvbG5hbWVzKGlkeCkpClggPC0gZGF0YWYgJT4lIAogIHNlbGVjdChzYW1wbGVOYW1lLElGKSAlPiUgdW5uZXN0KElGKSAlPiUKICB1bml0ZShDZWxsLHNhbXBsZU5hbWUsY2VsbCxzZXAgPSAnLScpICU+JSB0aWIyZGYoKQpYIDwtIFhbTWV0YXVtJENlbGwsXQphdmdtYXQgPC0gWCAlPiUgYXMubWF0cml4KCkgJT4lIHQgJT4lIHt0KC4lKiVpZHgpL2NvbFN1bXMoaWR4KX0gJT4lIHNjYWxlIApwaGVhdG1hcDo6cGhlYXRtYXAoYXZnbWF0LGNlbGx3aWR0aCA9IDEwLGNlbGxoZWlnaHQgPSAyMCxjb2xvcj12aXJpZGlzOjp2aXJpZGlzKDEwKSkKcGhlYXRtYXA6OnBoZWF0bWFwKGFzaW5oKGF2Z21hdCksY2VsbHdpZHRoID0gMTAsY2VsbGhlaWdodCA9IDIwLGNvbG9yPXZpcmlkaXM6OnZpcmlkaXMoMTApKQpgYGAKCmBgYHtyfQpkb21pMSA8LSBNZXRhdW0gJT4lCiAgbXV0YXRlKHg9Zmxvb3IoeC8xMDAwKSx5PWZsb29yKHkvMTAwMCkpICU+JQogIGNvdW50KHgseSxzYW1wbGVOYW1lLGNsdXN0ZXIpICU+JQogIGdyb3VwX2J5KHgseSxzYW1wbGVOYW1lKSAlPiUgYXJyYW5nZSgtbikgJT4lCiAgc3VtbWFyaXNlKHRvdCA9IHN1bShuKSwKICAgICAgICAgICAgbiA9IGhlYWQobiwxKSwKICAgICAgICAgICAgZG9tID0gaGVhZChjbHVzdGVyLDEpKSAlPiUKICB1bmdyb3VwKCkgJT4lCiAgbXV0YXRlKEFjY3AgPSBuL3RvdCkgCmRvbWkxICU+JQogIGdncGxvdChhZXMoeCx5LGNvbG9yPWRvbSxzaXplPW4sYWxwaGE9QWNjcCkpICsgCiAgdGhlbWVfbm9fYXhlcygpICsgZ2VvbV9wb2ludCgpICsgCiAgY29vcmRfZml4ZWQoKSArIGZhY2V0X3dyYXAofnNhbXBsZU5hbWUpICsKICB4bGltKC41LDIwLjUpICsgeWxpbSguNSwyMC41KSArIAogIGRjb2xvciArCiAgbGFicyhhbHBoYT0nQWNjcGFuY3knLHNpemU9J25Ub3RhbCBjZWxsJyxjb2xvcj0nZG9taW5hbnQgY2x1c3RlcicpICsKICB0aGVtZShzdHJpcC5iYWNrZ3JvdW5kID0gZWxlbWVudF9ibGFuaygpKSAKYGBgCgpgYGB7cn0KZG9taTIgPC0gTWV0YXVtICU+JQogIG11dGF0ZSh4PWZsb29yKHgvMTAwMCkseT1mbG9vcih5LzEwMDApLAogICAgICAgICBjbHVzdGVyID0gaWZlbHNlKGNsdXN0ZXIgPT0gMSwnQWN0aXZhdGVkJyxjbHVzdGVyKSwKICAgICAgICAgY2x1c3RlciA9IGlmZWxzZShjbHVzdGVyID09IDIsJ0VwaXRoZWxpYWwnLGNsdXN0ZXIpLAogICAgICAgICBjbHVzdGVyID0gaWZlbHNlKGNsdXN0ZXIgJWluJSAzOjUsJ01lc2VuY2h5bWFsJyxjbHVzdGVyKSwKICAgICAgICAgY2x1c3RlciA9IGZhY3RvcihjbHVzdGVyLGxldmVscyA9IGMoJ0FjdGl2YXRlZCcsJ0VwaXRoZWxpYWwnLCdNZXNlbmNoeW1hbCcpKSkgJT4lCiAgY291bnQoeCx5LHNhbXBsZU5hbWUsY2x1c3RlcikgJT4lCiAgZ3JvdXBfYnkoeCx5LHNhbXBsZU5hbWUpICU+JSBhcnJhbmdlKC1uKSAlPiUKICBzdW1tYXJpc2UodG90ID0gc3VtKG4pLAogICAgICAgICAgICBuID0gaGVhZChuLDEpLAogICAgICAgICAgICBkb20gPSBoZWFkKGNsdXN0ZXIsMSkpICU+JQogIHVuZ3JvdXAoKSAlPiUKICBtdXRhdGUoQWNjcCA9IG4vdG90KSAKZG9taTIgJT4lCiAgZ2dwbG90KGFlcyh4LHksY29sb3I9ZG9tLHNpemU9bixhbHBoYT1BY2NwKSkgKyAKICB0aGVtZV9ub19heGVzKCkgKyBnZW9tX3BvaW50KCkgKyAKICBjb29yZF9maXhlZCgpICsgZmFjZXRfd3JhcCh+c2FtcGxlTmFtZSkgKwogIHhsaW0oLjUsMjAuNSkgKyB5bGltKC41LDIwLjUpICsgCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IGRjb2xvciRwYWxldHRlKDgpW2MoMSwyLDgpXSkgKwogIGxhYnMoYWxwaGE9J0FjY3BhbmN5JyxzaXplPSduVG90YWwgY2VsbCcsY29sb3I9J2RvbWluYW50IGNsdXN0ZXInKSArCiAgdGhlbWUoc3RyaXAuYmFja2dyb3VuZCA9IGVsZW1lbnRfYmxhbmsoKSkgCmBgYAoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBgCgo=